#pragma region Copyright
/// <copyright>
/// Copyright (c) 2007 Ilia Shramko.
/// Released under the terms of the GNU General Public License.
/// </copyright>
#pragma endregion

#pragma once

struct RemoveFilterCommand
{
public:
	GUID ClassId;
};

struct InsertFilterCommand
{
	GUID ClassId;
	GUID AfterFilterClassId;
	GUID BeforeFilterClassId;
};

struct AppConfig
{
public:
	bool ForceMixingMode;
	int NumberOfStreams;
	bool CanReconnect;
	CSimpleArray<RemoveFilterCommand> RemoveFilters;
	CSimpleArray<InsertFilterCommand> InsertFilters;

	AppConfig()
	{
		ForceMixingMode = true;
		NumberOfStreams = 1;
		CanReconnect = true;
	} 
};

class Configuration
{
private:
	static Configuration _current;
	bool _initialized;
	bool _registerGraph;
	bool _multipleMixers;
	CString _appName;
	AppConfig _appConfig;
	bool _appConfigInitialized;
	CSimpleArray<CComBSTR> _enabledApps;

	HRESULT GetConfigurationFilePath(CString& filePath) const;
	HRESULT GetXmlConfig(IXMLDOMDocument** document) const;
	HRESULT ReadFilterGraphCommands(IXMLDOMNode* appNode, AppConfig& appConfig) const;
	HRESULT ReadFilterGraphRemoveCommand(IXMLDOMNode* removeFilterNode, AppConfig& appConfig) const;
	HRESULT ReadFilterGraphInsertCommand(IXMLDOMNode* insertFilterNode, AppConfig& appConfig) const;

	HRESULT ReadSettings(IXMLDOMNode* node, const wchar_t* xpath, CSimpleArray<CComBSTR>& values) const;
	HRESULT ReadSetting(IXMLDOMNode* node, const wchar_t* xpath, CComBSTR& value, bool isOptional) const;
	HRESULT ReadSetting(IXMLDOMNode* node, const wchar_t* xpath, bool& value, bool isOptional) const;
	HRESULT ReadSetting(IXMLDOMNode* node, const wchar_t* xpath, int& value, bool isOptional) const;
	HRESULT ReadSetting(IXMLDOMNode* node, const wchar_t* xpath, GUID& value, bool isOptional) const;

public:
	Configuration();
	~Configuration();

	HRESULT Initialize();

	AppConfig& GetCurrentAppConfig();
	CString& GetCurrentAppName();
	HRESULT IsCurrentAppEnabled();
	HRESULT IsAppEnabled(const wchar_t* appName);

	bool IsRegisterGraph() { return _registerGraph; }
	bool IsMultipleMixersAllowed() { return _multipleMixers; }

	static Configuration& Current();
};